package Demo1;

import java.util.Arrays;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 34255
 * Date: 2024-06-06
 * Time: 22:05
 */
public class ArrayList {
    public int[] array;//默认数组
    public int useSize;//数组使用长度

    public final static int ARRAY_COUNT = 5;//默认长度

    public ArrayList(){//构造方法
        this.array = new int[ARRAY_COUNT];//默认数组长度
    }

    private boolean isFull(){//判断数组是否满
        return this.useSize == this.array.length;
    }

    public void expansion(){//扩容
        this.array = Arrays.copyOf(this.array,2 * this.array.length);//扩容原长度的两倍
    }

    // 新增元素,默认在数组最后新增
    public void add(int data){
        if(this.isFull()){//判断数组是否满
            this.expansion();//扩容原长度的两倍
        }
        this.array[useSize++] = data;
    }

    public void posCheck1(int pos) throws PosException{
        if(pos < 0 || pos > this.useSize){
            throw new PosException("Pos位置不合法");
        }
    }

    public void posCheck2(int pos) throws PosException{
        if(pos < 0 || pos >= this.useSize){
            throw new PosException("Pos位置不合法");
        }
    }
    // 在 pos 位置新增元素
    public void add(int pos, int data) {
        try{
            posCheck1(pos);
            if(this.isFull()){//判断数组是否满
                this.expansion();//扩容原长度的两倍
            }
            for (int i = this.useSize; i >= pos ; i--) {//从pos位置整体往后移动一位
                array[i + 1] = array[i];
            }
            this.array[pos] = data;//赋值
            this.useSize++;
        }catch(PosException e){
            e.printStackTrace();
        }
    }

    // 判定是否包含某个元素
    public boolean contains(int toFind) {
        for (int i = 0; i < this.array.length; i++) {
            if(array[i] == toFind){
                return true;
            }
        }
        return false;
    }

    // 查找某个元素对应的位置
    public int indexOf(int toFind) {
        for (int i = 0; i < this.useSize; i++) {
            if(array[i] == toFind){
                return i;
            }
        }
        return -1;
    }

    //判断数组实际长度是否为空
    public void emptyCheck() throws EmptyException{
        if(this.useSize == 0){
            throw new EmptyException();
        }
    }
    // 获取 pos 位置的元素
    public int get(int pos) {
        //检验pos位置合法性
        try{
            emptyCheck();//判断数组实际长度是否为空
            posCheck2(pos);
            return this.array[pos];
        }catch(PosException e){
            e.printStackTrace();
        }catch (EmptyException e){
            e.printStackTrace();
        }
        return -1;
    }

    // 给 pos 位置的元素修改 value
    public void set(int pos, int value) {
        //检验pos位置合法性
        try{
            emptyCheck();//判断数组实际长度是否为空
            posCheck2(pos);
            this.array[pos] = value;
        }catch(PosException e){
            e.printStackTrace();
        }catch (EmptyException e){
            e.printStackTrace();
        }
    }

    //删除第一次出现的关键字key
    public void remove(int toRemove) {
        try{
            emptyCheck();
            int index = indexOf(toRemove);
            if(index == -1){
                return;
            }else{
                for (int i = index; i < this.useSize - 1; i++) {
                    array[i] = array[i + 1];
                }
                this.useSize--;
            }
        }catch(EmptyException e){
            e.printStackTrace();
        }
    }

    // 获取顺序表长度
    public int size() {
        return this.useSize;
    }

    // 清空顺序表
    public void clear() {
//        引用类型：假设清空顺序表，但是没把数组的元素置为null，那么数组里面元素还会引
//        用原本的对象，假设这些元素后面还是没有被使用，那就会造成内存泄漏，这边占用着内存空间没被使用，有引用变量引用着，造成对象空间无法被回收
//        for (int i = 0; i < this.useSize; i++) {
//            array[i] = null;
//        }
        this.useSize = 0;//仅限数组类型为基本数据类型
    }

    // 打印顺序表，注意：该方法并不是顺序表中的方法，为了方便看测试结果给出的
    public void display() {//遍历数组，打印每一个元素
        for (int i = 0; i < this.array.length; i++) {
            System.out.print(this.array[i] + " ");
        }
    }
}
